package org.jivesoftware.spark.phone;

import org.jivesoftware.resource.Res;
import org.jivesoftware.resource.SparkRes;
import org.jivesoftware.spark.ChatManager;
import org.jivesoftware.spark.SparkManager;
import org.jivesoftware.spark.plugin.ContextMenuListener;
import org.jivesoftware.spark.ui.ChatRoom;
import org.jivesoftware.spark.ui.ChatRoomButton;
import org.jivesoftware.spark.ui.ChatRoomListener;
import org.jivesoftware.spark.ui.ContactItem;
import org.jivesoftware.spark.ui.ContactList;
import org.jivesoftware.spark.ui.rooms.ChatRoomImpl;
import org.jivesoftware.spark.util.SwingWorker;
import org.jivesoftware.sparkimpl.plugin.phone.JMFInit;
import org.jivesoftware.Spark;

import javax.swing.Action;
import javax.swing.JMenu;
import javax.swing.JPopupMenu;
import javax.media.MediaLocator;
import javax.media.protocol.DataSource;

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class PhoneManager implements ChatRoomListener, ContextMenuListener
{
	private static PhoneManager singleton;
	private static final Object LOCK = new Object();
	
	private List<Phone> phones = new CopyOnWriteArrayList<Phone>();
	private List<String> currentCalls = new ArrayList<String>();
	static private MediaLocator mediaLocator = null;
	static private boolean useStaticLocator = false;
	static private DataSource ds;
	
	public static PhoneManager getInstance()
	{
		synchronized(LOCK)
		{
			if (null == singleton)
			{
				PhoneManager controller = new PhoneManager();
				singleton = controller;
				return controller;
			}
		}
		return singleton;
	}
	
	private PhoneManager()
	{
		JMFInit.start(false);
		if (Spark.isVista() || Spark.isLinux())
		{
			setUseStaticLocator(true);
		}
	}
	
	private void addListeners()
	{
		final ChatManager chatManager = SparkManager.getChatManager();
		chatManager.addChatRoomListener(this);
		
		final ContactList contactList = SparkManager.getWorkspace().getContactList();
		contactList.addContextMenuListener(this);
	}
	
	public void addPhone(Phone phone)
	{
		if (phones.isEmpty())
		{
			addListeners();
		}
		
		phones.add(phone);
	}
	
	public void removePhone(Phone phone)
	{
		phones.remove(phone);
	}
	
	public void chatRoomOpened(final ChatRoom room)
	{
		if (!phones.isEmpty() && room instanceof ChatRoomImpl)
		{
			final ChatRoomImpl chatRoomImpl = (ChatRoomImpl)room;
			final ChatRoomButton dialButton = new ChatRoomButton(SparkRes.getImageIcon(SparkRes.DIAL_PHONE_IMAGE_24x24));
			dialButton.setToolTipText(Res.getString("tooltip.place.voice.call"));
			
			final List<Action> actions = new ArrayList<Action>();
			SwingWorker actionWorker = new SwingWorker()
			{
				public Object construct()
				{
					for (Phone phone : phones)
					{
						final Collection<Action> phoneActions = phone.getPhoneActions(chatRoolImpl.getParticipantJID());
						if (phoneActions != null)
						{
							for (Action action : phoneActions)
							{
								actions.add(action);
							}
						}
					}
					return actions;
				}
				
				public void finished()
				{
					if (!actions.isEmpty())
					{
						room.getToolBar().addChatRoomButton(dialButton);
						room.getToolBar().invalidate();
						room.getToolBar().validate();
						room.getToolBar().repaint();
					}
				}
			};
			
			actionWorker.start();
			
			dialButton.addMouseListener(new MouseAdapter()
			{
				public void mousePressed(final MouseEvent e)
				{
					SwingWorker worker = new SwingWorker()
					{
						public Object construct()
						{
							try
							{
								Thread.sleep(50);
							}
							catch(InterruptedException e1)
							{
								e1.printStackTrace();
							}
							return true;
						}
						
						public void finished()
						{
							if (actions.size() > 0)
							{
								final JPopupMenu menu = new JPopupMenu();
								for (Action action : actions)
								{
									menu.add(action);
								}
								
								menu.show(dialButton, e.getX(), e.getY());
							}
						}
					};
					worker.start();
				}
			});
		}
	}
	
	public void chatRoomLeft(ChatRoom room)
	{
	}
	
	public void chatRoomClosed(ChatRoom room)
	{
	}
	
	public void chatRoomActivated(ChatRoom room)
	{
	}
	
	public void userHasJoined(ChatRoom room, String userid)
	{
	}
	
	public void userHasLeft(ChatRoom room, String userid)
	{
	}
	
	public void poppingUp(Object object, final JPopupMenu popup)
	{
		if (!phones.isEmpty())
		{
			if (object instanceof ContactItem)
			{
				 final ContactItem contactItem = (ContactItem) object;
				 final List<Action> actions = new ArrayList<Action>();
				 
				 SwingWorker worker = new SwingWorker()
				 {
					public Object construct()
					{
						final Collection<Action> itemActions = phone.getPhoneActions(contactItem.getJID());
						for (Action action : itemActions)
						{
							actions.add(action);
						}
						
						return null;
					}
					
					public void finished()
					{
						if (actions.size() > 0)
						{
							final JMenu dialMenu = new JMenu(Res.getString("title.dial.phone"));
							dialMenu.setIcon(SparkRes.getImageIcon(SparkRes.DIAL_PHONE_IMAGE_16x16));
							
							for (Action action : actions)
							{
								dialMenu.add(action);
							}
							
							
						}
					}
				 }
			}
		}
	}
}
